using System;
using System.Collections.Generic;
using System.Text;
using RaisingStudio.Data.Common.Managers;
using RaisingStudio.Data.Common.Factories;

namespace RaisingStudio.Data.Common
{
    public class CommonDatabase : DataContextBase, ICommonDatabase
    {
        #region Constructor
        /// <summary>
        /// Constructor
        /// </summary>
        public CommonDatabase()
        {
        }

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="connection">database connection.</param>
        public CommonDatabase(System.Data.IDbConnection connection)
            : base(connection)
        {
        }

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="transactionManager">database transaction manager.</param>
        public CommonDatabase(TransactionManager transactionManager)
            : base(transactionManager)
        {
        }

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="connectionName">the name of connection.</param>
        public CommonDatabase(string connectionName)
            : base(connectionName)
        {
        }

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="databaseType">database type.</param>
        /// <param name="connectionString">connection string.</param>
        public CommonDatabase(DatabaseType databaseType, string connectionString)
            : base(databaseType, connectionString)
        {
        }

        public CommonDatabase(string providerName, string connectionString)
            : base(providerName, connectionString)
        {
        }

        public CommonDatabase(TransactionManager transactionManager, LogManager logManager)
            : base(transactionManager, logManager)
        {
        }
  
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="transactionManager">database transaction manager.</param>
        public CommonDatabase(TransactionManager transactionManager, LogManager logManager, DatabaseType databaseType, string providerName)
            : base(transactionManager, logManager, databaseType, providerName)
        {
        }
      #endregion
        
        public virtual DatabaseType GetDatabaseType()
        {
            if ((base.DatabaseType == DatabaseType.OTHER) && (!ProviderManager.Instance.ProviderExists(this.ProviderName)))
            {
                DatabaseType databaseType = ConnectionFactory.GetDatabaseType(base.Connection);
                return databaseType;
            }
            return base.DatabaseType;
        }

        protected virtual System.Data.IDbCommand ConvertCommand(CommonCommand commonCommand)
        {
            DatabaseType databaseType = GetDatabaseType();
            return CommandConverter.Convert(commonCommand, this.connection, databaseType, base.ProviderName);
        }


        public int ExecuteNonQueryCommand(CommonCommand commonCommand, string transactionID)
        {
            return ExecuteNonQueryCommand(commonCommand, this.TransactionManager.GetTransaction(transactionID));
        }

        public int ExecuteNonQueryCommand(CommonCommand commonCommand)
        {
            return ExecuteNonQueryCommand(commonCommand, this.TransactionManager.DefaultTransaction);
        }

        protected virtual int ExecuteNonQueryCommand(CommonCommand commonCommand, System.Data.IDbTransaction transaction)
        {
            System.Data.IDbCommand command = ConvertCommand(commonCommand);
            if (transaction != null)
            {
                command.Transaction = transaction;
            }
            WriteLog(command);
            int value = RaisingStudio.Data.Common.Database.ExecuteNonQueryCommand(command);
            // set out parameter value.
            CommandConverter.FeedbackParameters(ref commonCommand, command);
            return value;
        }


        public System.Data.IDataReader ExecuteReaderCommand(CommonCommand commonCommand, string transactionID)
        {
            return ExecuteReaderCommand(commonCommand, this.TransactionManager.GetTransaction(transactionID));
        }

        public System.Data.IDataReader ExecuteReaderCommand(CommonCommand commonCommand)
        {
            return ExecuteReaderCommand(commonCommand, this.TransactionManager.DefaultTransaction);
        }

        protected virtual System.Data.IDataReader ExecuteReaderCommand(CommonCommand commonCommand, System.Data.IDbTransaction transaction)
        {
            System.Data.IDbCommand command = ConvertCommand(commonCommand);
            if (transaction != null)
            {
                command.Transaction = transaction;
            }
            WriteLog(command);
            System.Data.IDataReader dataReader = RaisingStudio.Data.Common.Database.ExecuteReaderCommand(command);
            // set out parameter value.
            CommandConverter.FeedbackParameters(ref commonCommand, command);
            return dataReader;
        }


        public object ExecuteScalarCommand(CommonCommand commonCommand, string transactionID)
        {
            return ExecuteScalarCommand(commonCommand, this.TransactionManager.GetTransaction(transactionID));
        }
   
        public object ExecuteScalarCommand(CommonCommand commonCommand)
        {
            return ExecuteScalarCommand(commonCommand, this.TransactionManager.DefaultTransaction);
        }

        public object ExecuteScalarCommand(CommonCommand commonCommand, System.Data.IDbTransaction transaction)
        {
            System.Data.IDbCommand command = ConvertCommand(commonCommand);
            if (transaction != null)
            {
                command.Transaction = transaction;
            }
            WriteLog(command);
            object value = RaisingStudio.Data.Common.Database.ExecuteScalarCommand(command);
            // set out parameter value.
            CommandConverter.FeedbackParameters(ref commonCommand, command);
            return value;
        }
    }
}
